package com.dog.basics.service.mtkj.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dog.basics.bean.dto.admin.mtkj.CouponFromDto;
import com.dog.basics.bean.dto.api.mtkj.ApiCouponFromDto;
import com.dog.basics.bean.model.common.DogUser;
import com.dog.basics.bean.model.mtkj.*;
import com.dog.basics.bean.vo.admin.mtkj.CouponFromVo;
import com.dog.basics.bean.vo.api.mtkj.ApiCouponInfoVo;
import com.dog.basics.common.util.PageParam;
import com.dog.basics.dao.common.DogUserMapper;
import com.dog.basics.dao.mtkj.*;
import com.dog.basics.security.util.SecurityUtils;
import com.dog.basics.service.mtkj.IMtCouponService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 优惠券领用表 服务实现类
 * </p>
 *
 * @author wph
 * @since 2020-11-09
 */
@Service
@AllArgsConstructor
public class MtCouponServiceImpl extends ServiceImpl<MtCouponMapper, MtCoupon> implements IMtCouponService {

    private final MtDiscountCouponMapper discountCouponMapper;
    private final MtShoppingMapper shoppingMapper;
    private final MtOrderMapper orderMapper;
    private final DogUserMapper userMapper;
    private final MtDeviceOrderMapper mtDeviceOrderMapper;
    /**
     * admin服务
     * 查询优惠券领用列表
     *
     * @param: page
     * @param: fromDto
     * @returns
     * @author hangdy
     * @date: 2020/11/14 14:20
     */
    @Override
    public IPage<CouponFromVo> adimeFindCouponList(PageParam page, CouponFromDto fromDto) {

        //2.分页查询
        IPage iPage = this.page(page, Wrappers.<MtCoupon>lambdaQuery()
                .eq(ObjectUtil.isNotNull(fromDto.getUseOrderId()), MtCoupon::getUseOrderId, fromDto.getUseOrderId())
                .eq(ObjectUtil.isNotNull(fromDto.getCouponType()), MtCoupon::getCouponType, fromDto.getCouponType())
                .eq(ObjectUtil.isNotNull(fromDto.getShopId()), MtCoupon::getShopId, fromDto.getShopId())
                .eq(ObjectUtil.isNotNull(fromDto.getStatus()), MtCoupon::getStatus, fromDto.getStatus())

                .like(ObjectUtil.isNotNull(fromDto.getDiscountCouponName()), MtCoupon::getDiscountCouponName, fromDto.getDiscountCouponName())
                .like(ObjectUtil.isNotNull(fromDto.getUserId()), MtCoupon::getUserId, fromDto.getUserId())
        );

        List<MtCoupon> couponList = iPage.getRecords();
        List<CouponFromVo> couponFromVoList = couponList.stream().map(e -> {
            CouponFromVo vo = BeanUtil.copyProperties(e, CouponFromVo.class);

            MtShopping shopping = shoppingMapper.selectById(e.getShopId());
            vo.setShopName(ObjectUtil.isNotNull(shopping.getName()) ? shopping.getName() : "");
            //判断是否有订单
            if (e.getUseOrderId() != null && e.getUseOrderId() != -1L) {
                MtOrder order = orderMapper.selectById(e.getUseOrderId());
                if (order != null) {
                    vo.setUseOrderNo(ObjectUtil.isNotNull(order.getOrderNo()) ? order.getOrderNo() : "");
                }

            }

            //判断是否有使用人
            if (e.getUserId() != null && e.getUserId() != -1L) {
                DogUser user = userMapper.selectById(e.getUserId());
                if (user != null) {
                    vo.setUserName(ObjectUtil.isNotNull(user.getNickName()) ? user.getNickName() : "");
                }

            }

            return vo;
        }).collect(Collectors.toList());

        return iPage.setRecords(couponFromVoList);
    }

    /**
     * Admin服务
     * 超级管理员删除操作
     *
     * @param: id
     * @returns
     * @author hangdy
     * @date: 2020/11/14 15:17
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean adminDeleteById(Long id) {

        //2.查询优惠券是否存在
        MtCoupon coupon = this.getById(id);
        Validator.validateNotNull(coupon, "优惠券不存在");
        //3.删除操作
        this.removeById(id);
        return Boolean.TRUE;
    }

    /**
     * 分页查询用户优惠券信息
     * 1.查询用户某个状态下所有优惠券
     * 2.查询用户某个店铺中所有优惠券
     *
     * @param page
     * @param couponFromDto
     * @return
     */
    @Override
    public IPage<ApiCouponInfoVo> getPageList(PageParam page, ApiCouponFromDto couponFromDto) {

        //分页查询信息
        IPage iPage = this.page(page, Wrappers.<MtCoupon>lambdaQuery()
                .eq(MtCoupon::getUserId, couponFromDto.getUserId())
                .and(Wrappers -> Wrappers.eq(ObjectUtil.isNotNull(couponFromDto.getShopId()), MtCoupon::getShopId, couponFromDto.getShopId()).or().eq(MtCoupon::getType, 1))
                .eq(ObjectUtil.isNotNull(couponFromDto.getStatus()), MtCoupon::getStatus, couponFromDto.getStatus())
                .orderBy(true, false, MtCoupon::getCreateTime));
        List<MtCoupon> couponList = iPage.getRecords();
        //将实体类转换成Vo
        iPage.setRecords(couponList.stream().map(e -> {
            ApiCouponInfoVo apiCouponInfoVo = BeanUtil.copyProperties(e, ApiCouponInfoVo.class);
            apiCouponInfoVo.setDiscountCouponEndTime(e.getEndTime());
            apiCouponInfoVo.setDiscountCouponStartTime(e.getStartTime());
            apiCouponInfoVo.setDiscountCouponValue(e.getMoney());
            MtShopping shopping = shoppingMapper.selectById(e.getShopId());
            if (shopping != null) {
                apiCouponInfoVo.setShopName(ObjectUtil.isNotNull(shopping) ? shopping.getName() : "");
            }

            return apiCouponInfoVo;
        }).collect(Collectors.toList()));
        return iPage;
    }

    /**
     * 用户领取优惠券
     *
     * @param discountCouponId
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveCoupon(Long discountCouponId) {
        //1.查询优惠券信息
        MtDiscountCoupon discountCoupon = discountCouponMapper.selectById(discountCouponId);
        Validator.validateNotNull(discountCoupon, "未找到优惠券信息");
        //1.1判断用户是否领取过优惠券
        List<MtCoupon> couponList = this.list(Wrappers.<MtCoupon>lambdaQuery().eq(MtCoupon::getDiscountCouponId, discountCouponId).eq(MtCoupon::getUserId, SecurityUtils.getUser().getUserId()));
        if (couponList.size() > 0) {
            Validator.validateTrue(false, "已领过该优惠券");
        }

        if (discountCoupon.getType() == 1) {
            //判断是够可以领取
            BigDecimal userMoney=mtDeviceOrderMapper.getUserMoney(SecurityUtils.getUser().getUserId());
            Validator.validateTrue(userMoney.compareTo(discountCoupon.getDeviceMoney())>=0,"您不符合领取规则!");
        }
        //2.生成用户优惠券信息并保存
        MtCoupon coupon = new MtCoupon();

        //设置优惠券领取时 创建时间贺创建人
        coupon.setCreateBy(SecurityUtils.getUser().getUserId());
        coupon.setCreateTime(DateUtil.currentSeconds());

        //设置优惠券基本信息 start
        coupon.setShopId(discountCoupon.getShopId());
        coupon.setDiscountCouponId(discountCoupon.getId());
        coupon.setDiscountCouponName(discountCoupon.getDiscountCouponName());
        coupon.setCouponType(discountCoupon.getCouponType());
        coupon.setEndTime(discountCoupon.getDiscountCouponEndTime());
        //设置优惠券为已领取
        coupon.setType(discountCoupon.getType());
        coupon.setStatus(1);
        coupon.setFetchTime(DateUtil.currentSeconds());
        coupon.setStartTime(discountCoupon.getDiscountCouponStartTime());
        coupon.setUserId(SecurityUtils.getUser().getUserId());
        coupon.setContent(discountCoupon.getContent());
        //设置优惠券基本信息 end

        //设置优惠券金额信息 start
        coupon.setMoney(discountCoupon.getDiscountCouponValue());
        coupon.setMinimumConsumption(discountCoupon.getMinimumConsumption());
        coupon.setDiscount(discountCoupon.getDiscount());
        //设置优惠券金额信息 end


        Validator.validateTrue(this.save(coupon), "优惠券领取失败");

        return Boolean.TRUE;
    }

    /**
     * 删除用户已领取的优惠券
     * 先判断优惠券是否存在，再判断优惠券是否是该用户领取
     * 存在且该用户领取则删除成功
     *
     * @param: id  优惠券id
     * @returns
     * @author hangdy
     * @date: 2020/11/13 11:10
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteCoupon(Long id) {
        MtCoupon coupon = this.getById(id);
        Validator.validateNotNull(coupon, "优惠券不存在");
        Validator.validateEqual(coupon.getUserId(), SecurityUtils.getUser().getUserId(), "无法删除优惠券");
        Validator.validateTrue(this.removeById(id), "删除失败");
        return Boolean.TRUE;
    }

}
